#include <iostream>
#include <string>
#include <unordered_map>

namespace {

class TrieNode;
typedef std::unordered_map<uint8_t, TrieNode*> MapTrie;
class TrieNode {
public:
    TrieNode() {
    }

    TrieNode* Get(uint8_t k) {
        auto iter = this->map.find(k);
        if (iter == this->map.end()) {
            return NULL;
        }
        else {
            return iter->second;
        }
    }

    void Put(uint8_t k, TrieNode *node) {
        this->map[k] = node;
    }

    void SetEnd() { this->isEnd = true; }
    bool IsEnd() { return this->isEnd; }

private:
    MapTrie map;
    bool isEnd;
};

class Trie {
public:
    Trie() {
        root = new TrieNode();
    }

    void Insert(std::string word) {
        TrieNode *node = root;
        for (auto c: word) {
            TrieNode *temp = node->Get(c);
            if (!temp) {
                temp = new TrieNode();
                node->Put(c, temp);
            }
            node = temp;
        }
        node->SetEnd();
    }

    TrieNode* SearchPrefix(std::string word) {
        TrieNode *node = root;
        for (auto c: word) {
            node = node->Get(c);
            if (!node) {
                return NULL;
            }
        }
        return node;
    }

    bool Search(std::string word) {
        TrieNode *node = SearchPrefix(word);
        return node && node->IsEnd();
    }
    
private:
    TrieNode *root;
};


void Handle() {
    Trie *pt = new Trie();
    pt->Insert("春节");
    pt->Insert("春节7天");
    pt->Insert("夏天");
    std::string word = "春节7天";
    std::cout << "find: " << word << " " << pt->Search(word) << std::endl;
    word = "春节";
    std::cout << "find: " << word << " " << pt->SearchPrefix(word) << std::endl;
    word = "春节";
    std::cout << "find: " << word << " " << pt->Search(word) << std::endl;
}

}


void HandleTrie() {
    Handle();
}